package leetcode.code2034;

import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
//执行用时：83 ms, 在所有 Java 提交中击败了83.74%的用户
//
//内存消耗：90.2 MB, 在所有 Java 提交中击败了94.81%的用户
//
//通过测试用例：18 / 18
public class StockPrice {

	PriorityQueue<Integer> max;
	PriorityQueue<Integer> min;
	int latesttime;
	int latestprice;
	Map<Integer, Integer> hashPrice;
	Map<Integer, Integer> hashTime;

	public StockPrice() {
		latesttime = -1;
		latestprice = -1;
		max = new PriorityQueue<>((a, b) -> b - a);
		min = new PriorityQueue<>((a, b) -> a - b);
		hashPrice = new HashMap<>();
		hashTime = new HashMap<>();
	}

	public void update(int timestamp, int price) {
		if (timestamp >= latesttime) {
			latestprice = price;
			latesttime = timestamp;// 面壁思过
		}
		Integer update = hashTime.getOrDefault(timestamp, null);
		hashTime.put(timestamp, price);
		if (update != null) {
			int exists = hashPrice.get(update);
			if (exists > 1) {
				hashPrice.put(update, exists - 1);
			} else {
				hashPrice.remove(update);
			}
		}
		update = hashPrice.getOrDefault(price, 0);
		hashPrice.put(price, update + 1);
		max.add(price);
		min.add(price);
	}

	public int current() {
		return latestprice;
	}

	public int maximum() {
		int ans = max.peek();
		while (!hashTime.containsValue(ans)) {
			max.poll();
			ans = max.peek();
		}
		return ans;
	}

	public int minimum() {
		int ans = min.peek();
		while (!hashTime.containsValue(ans)) {
			min.poll();
			ans = min.peek();
		}
		return ans;
	}

	public static void main(String[] args) {
		StockPrice stockPrice = new StockPrice();
		stockPrice.update(1, 10); // 时间戳为 [1] ，对应的股票价格为 [10] 。
		stockPrice.update(2, 5); // 时间戳为 [1,2] ，对应的股票价格为 [10,5] 。
		int ans = 0;
		ans = stockPrice.current(); // 返回 5 ，最新时间戳为 2 ，对应价格为 5 。
		System.out.println(ans);
		ans = stockPrice.maximum(); // 返回 10 ，最高价格的时间戳为 1 ，价格为 10 。
		System.out.println(ans);
		stockPrice.update(1, 3); // 之前时间戳为 1 的价格错误，价格更新为 3 。
									// 时间戳为 [1,2] ，对应股票价格为 [3,5] 。
		ans = stockPrice.maximum(); // 返回 5 ，更正后最高价格为 5 。
		System.out.println(ans);
		stockPrice.update(4, 2); // 时间戳为 [1,2,4] ，对应价格为 [3,5,2] 。
		ans = stockPrice.minimum(); // 返回 2 ，最低价格时间戳为 4 ，价格为 2 。
		System.out.println(ans);

	}

}
